{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:53:20.523512Z",
     "iopub.status.busy": "2023-11-08T00:53:20.523308Z",
     "iopub.status.idle": "2023-11-08T00:53:21.850097Z",
     "shell.execute_reply": "2023-11-08T00:53:21.849467Z",
     "shell.execute_reply.started": "2023-11-08T00:53:20.523486Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import seaborn as sns\n",
    "import lightgbm as lgb\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.metrics import roc_auc_score\n",
    "from sklearn.metrics import f1_score\n",
    "from sklearn.model_selection import StratifiedKFold\n",
    "\n",
    "def local_f1(y_pred, y_true): \n",
    "    list_pred = y_pred['TD_IND'].to_list()\n",
    "    list_pred.extend(y_pred['FNCG_IND'].to_list())\n",
    "    list_pred.extend(y_pred['FUND_IND'].to_list())\n",
    "    list_pred.extend(y_pred['INSUR_IND'].to_list())\n",
    "    list_pred.extend(y_pred['IL_IND'].to_list())\n",
    "    \n",
    "    list_true = y_true['TD_IND'].to_list() \n",
    "    list_true.extend(y_true['FNCG_IND'].to_list()) \n",
    "    list_true.extend(y_true['FUND_IND'].to_list())\n",
    "    list_true.extend(y_true['INSUR_IND'].to_list())\n",
    "    list_true.extend(y_true['IL_IND'].to_list())\n",
    "    return f1_score(list_pred ,list_true )\n",
    "\n",
    "def kfold_stats_feature(train, test, feats, k,label='label'):\n",
    "    folds = StratifiedKFold(n_splits=k, shuffle=True, random_state=2020)  # 这里最好和后面模型的K折交叉验证保持一致\n",
    "\n",
    "    train['fold'] = None\n",
    "    for fold_, (trn_idx, val_idx) in enumerate(folds.split(train, train[label])):\n",
    "        train.loc[val_idx, 'fold'] = fold_\n",
    "\n",
    "    kfold_features = []\n",
    "    for feat in feats:\n",
    "        nums_columns = [label]\n",
    "        for f in nums_columns:\n",
    "            colname = feat + '_' + f + '_kfold_mean'\n",
    "            kfold_features.append(colname)\n",
    "            train[colname] = None\n",
    "            for fold_, (trn_idx, val_idx) in enumerate(folds.split(train, train[label])):\n",
    "                tmp_trn = train.iloc[trn_idx]\n",
    "                order_label = tmp_trn.groupby([feat])[f].mean()\n",
    "                tmp = train.loc[train.fold == fold_, [feat]]\n",
    "                train.loc[train.fold == fold_, colname] = tmp[feat].map(order_label)\n",
    "                # fillna\n",
    "                global_mean = train[f].mean()\n",
    "                train.loc[train.fold == fold_, colname] = train.loc[train.fold == fold_, colname].fillna(global_mean)\n",
    "            train[colname] = train[colname].astype(float)\n",
    "\n",
    "        for f in nums_columns:\n",
    "            colname = feat + '_' + f + '_kfold_mean'\n",
    "            test[colname] = None\n",
    "            order_label = train.groupby([feat])[f].mean()\n",
    "            test[colname] = test[feat].map(order_label)\n",
    "            # fillna\n",
    "            global_mean = train[f].mean()\n",
    "            test[colname] = test[colname].fillna(global_mean)\n",
    "            test[colname] = test[colname].astype(float)\n",
    "    del train['fold']\n",
    "    return train, test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:53:21.851391Z",
     "iopub.status.busy": "2023-11-08T00:53:21.851196Z",
     "iopub.status.idle": "2023-11-08T00:53:21.854534Z",
     "shell.execute_reply": "2023-11-08T00:53:21.853921Z",
     "shell.execute_reply.started": "2023-11-08T00:53:21.851366Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "train_path = '../../contest/train'\n",
    "stage_path = '../../contest/A'\n",
    "stage = 'A'\n",
    "labels = ['TD_IND', 'FNCG_IND', 'FUND_IND', 'INSUR_IND', 'IL_IND']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:53:21.855764Z",
     "iopub.status.busy": "2023-11-08T00:53:21.855592Z",
     "iopub.status.idle": "2023-11-08T00:53:21.955685Z",
     "shell.execute_reply": "2023-11-08T00:53:21.955152Z",
     "shell.execute_reply.started": "2023-11-08T00:53:21.855743Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "df_train = pd.read_csv(os.path.join(train_path,'GSLD_TARGET_TRAIN.csv'))\n",
    "df_test = pd.read_csv(os.path.join(stage_path,f'GSLD_TARGET_A.csv'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:53:21.956845Z",
     "iopub.status.busy": "2023-11-08T00:53:21.956670Z",
     "iopub.status.idle": "2023-11-08T00:53:24.319723Z",
     "shell.execute_reply": "2023-11-08T00:53:24.319073Z",
     "shell.execute_reply.started": "2023-11-08T00:53:21.956823Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "GSLD_NATURE_CUST_A.csv (5000, 4)\n",
      "GSLD_MB_BASICS_A.csv (5000, 7)\n",
      "GSLD_MB_TRNFLW_A.csv (5000, 15)\n",
      "GSLD_MB_QRYTRNFLW_A.csv (5000, 20)\n",
      "GSLD_AGET_PAY_A.csv (5000, 26)\n",
      "GSLD_ASSET_DEBT_A.csv (5000, 86)\n",
      "GSLD_TR_APS_A.csv (5000, 142)\n"
     ]
    }
   ],
   "source": [
    "del df_test['DATA_DAT'], df_train['DATA_DAT']\n",
    "\n",
    "for file in ['GSLD_NATURE_CUST.csv', 'GSLD_MB_BASICS.csv', 'GSLD_MB_TRNFLW.csv', 'GSLD_MB_QRYTRNFLW.csv', 'GSLD_AGET_PAY.csv'\n",
    "             , 'GSLD_ASSET_DEBT.csv'\n",
    "             , 'GSLD_TR_APS.csv']:\n",
    "    df_tmp = pd.read_csv(os.path.join('data',file))\n",
    "    df_train = df_train.merge(df_tmp,on='CUST_NO',how='left')\n",
    "    \n",
    "for file in ['GSLD_NATURE_CUST_A.csv', 'GSLD_MB_BASICS_A.csv', 'GSLD_MB_TRNFLW_A.csv', 'GSLD_MB_QRYTRNFLW_A.csv', 'GSLD_AGET_PAY_A.csv'\n",
    "            , 'GSLD_ASSET_DEBT_A.csv'\n",
    "            , 'GSLD_TR_APS_A.csv']:\n",
    "    df_tmp = pd.read_csv(os.path.join('data',file))\n",
    "    df_test = df_test.merge(df_tmp,on='CUST_NO',how='left')\n",
    "    print(file, df_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:53:24.320900Z",
     "iopub.status.busy": "2023-11-08T00:53:24.320700Z",
     "iopub.status.idle": "2023-11-08T00:53:55.322822Z",
     "shell.execute_reply": "2023-11-08T00:53:55.322145Z",
     "shell.execute_reply.started": "2023-11-08T00:53:24.320876Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/woody/anaconda3/lib/python3.8/site-packages/sklearn/model_selection/_split.py:670: UserWarning: The least populated class in y has only 3 members, which is less than n_splits=5.\n",
      "  warnings.warn((\"The least populated class in y has only %d\"\n",
      "/home/woody/anaconda3/lib/python3.8/site-packages/sklearn/model_selection/_split.py:670: UserWarning: The least populated class in y has only 3 members, which is less than n_splits=5.\n",
      "  warnings.warn((\"The least populated class in y has only %d\"\n",
      "/home/woody/anaconda3/lib/python3.8/site-packages/sklearn/model_selection/_split.py:670: UserWarning: The least populated class in y has only 3 members, which is less than n_splits=5.\n",
      "  warnings.warn((\"The least populated class in y has only %d\"\n",
      "/home/woody/anaconda3/lib/python3.8/site-packages/sklearn/model_selection/_split.py:670: UserWarning: The least populated class in y has only 3 members, which is less than n_splits=5.\n",
      "  warnings.warn((\"The least populated class in y has only %d\"\n",
      "/home/woody/anaconda3/lib/python3.8/site-packages/sklearn/model_selection/_split.py:670: UserWarning: The least populated class in y has only 3 members, which is less than n_splits=5.\n",
      "  warnings.warn((\"The least populated class in y has only %d\"\n",
      "/home/woody/anaconda3/lib/python3.8/site-packages/sklearn/model_selection/_split.py:670: UserWarning: The least populated class in y has only 3 members, which is less than n_splits=5.\n",
      "  warnings.warn((\"The least populated class in y has only %d\"\n",
      "/home/woody/anaconda3/lib/python3.8/site-packages/sklearn/model_selection/_split.py:670: UserWarning: The least populated class in y has only 3 members, which is less than n_splits=5.\n",
      "  warnings.warn((\"The least populated class in y has only %d\"\n"
     ]
    }
   ],
   "source": [
    "combine_labels = ['00010','00011','10010','01010','01110','10110']\n",
    "def add_combine_labels(df_train1):\n",
    "    df_train1['label'] = df_train1.TD_IND.astype('str')+df_train1.FNCG_IND.astype('str')+df_train1.FUND_IND.astype('str')+df_train1.INSUR_IND.astype('str')+df_train1.IL_IND.astype('str')\n",
    "    for label_str in combine_labels:\n",
    "        df_train1[label_str] = df_train1['label'].apply(lambda x: 1 if x==label_str else 0)\n",
    "    return df_train1\n",
    "df_train = add_combine_labels(df_train)\n",
    "\n",
    "# label出现1的个数编码\n",
    "label_sum_num_list = []\n",
    "label_sum_list = ['label_sum_'+str(i) for i in label_sum_num_list]\n",
    "for i, ls in enumerate(label_sum_list):\n",
    "    df_train[ls] = df_train[labels].sum(axis=1).apply(lambda x: 1 if x==label_sum_num_list[i] else 0)\n",
    "\n",
    "target_encoder_columns = [\n",
    "'prov_cd'\n",
    ",'unit_typ_cd'\n",
    ",'MB_REG_PROV'\n",
    ",'MS_IND'\n",
    ",'NTRL_CUST_SEX_CD'\n",
    ",'NTRL_RANK_CD'\n",
    "]\n",
    "\n",
    "# \n",
    "for label in combine_labels+label_sum_list:\n",
    "    df_train, df_test = kfold_stats_feature(df_train, df_test, target_encoder_columns, 5, label=label)\n",
    "\n",
    "# \n",
    "labels = ['TD_IND','FNCG_IND','FUND_IND','INSUR_IND','IL_IND']\n",
    "features = [x for x in df_train.columns if x not in label_sum_list+combine_labels+labels+['label', 'DATA_DAT', 'CUST_NO']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:53:55.324210Z",
     "iopub.status.busy": "2023-11-08T00:53:55.323802Z",
     "iopub.status.idle": "2023-11-08T00:53:55.329943Z",
     "shell.execute_reply": "2023-11-08T00:53:55.329443Z",
     "shell.execute_reply.started": "2023-11-08T00:53:55.324160Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((60000, 190), (5000, 178))"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_train.shape, df_test.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:53:55.330913Z",
     "iopub.status.busy": "2023-11-08T00:53:55.330741Z",
     "iopub.status.idle": "2023-11-08T00:53:55.334833Z",
     "shell.execute_reply": "2023-11-08T00:53:55.334253Z",
     "shell.execute_reply.started": "2023-11-08T00:53:55.330890Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "params = {'num_leaves': 2**5-1,\n",
    "              'min_data_in_leaf': 300, \n",
    "              'objective':'binary',\n",
    "              'max_depth': 5,\n",
    "              'learning_rate': 0.03,\n",
    "              'boosting': 'gbdt',\n",
    "              'feature_fraction': 0.9,\n",
    "              'bagging_fraction': 0.8,\n",
    "              'bagging_seed': 11,\n",
    "              'metric': 'auc',\n",
    "              'seed':1024,\n",
    "              'lambda_l1': 0.2,\n",
    "              'nthread':10,\n",
    "              'verbose':-1,\n",
    "         }"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:53:55.335762Z",
     "iopub.status.busy": "2023-11-08T00:53:55.335597Z",
     "iopub.status.idle": "2023-11-08T00:57:32.794249Z",
     "shell.execute_reply": "2023-11-08T00:57:32.793677Z",
     "shell.execute_reply.started": "2023-11-08T00:53:55.335741Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Fold 0\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/woody/anaconda3/lib/python3.8/site-packages/lightgbm/engine.py:181: UserWarning: 'early_stopping_rounds' argument is deprecated and will be removed in a future release of LightGBM. Pass 'early_stopping()' callback via 'callbacks' argument instead.\n",
      "  _log_warning(\"'early_stopping_rounds' argument is deprecated and will be removed in a future release of LightGBM. \"\n",
      "/home/woody/anaconda3/lib/python3.8/site-packages/lightgbm/engine.py:239: UserWarning: 'verbose_eval' argument is deprecated and will be removed in a future release of LightGBM. Pass 'log_evaluation()' callback via 'callbacks' argument instead.\n",
      "  _log_warning(\"'verbose_eval' argument is deprecated and will be removed in a future release of LightGBM. \"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[299]\ttraining's auc: 0.880324\tvalid_1's auc: 0.813759\n",
      "Fold 1\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[281]\ttraining's auc: 0.877113\tvalid_1's auc: 0.817417\n",
      "Fold 2\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[323]\ttraining's auc: 0.884277\tvalid_1's auc: 0.811916\n",
      "Fold 3\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "[1000]\ttraining's auc: 0.947147\tvalid_1's auc: 0.823485\n",
      "Early stopping, best iteration is:\n",
      "[679]\ttraining's auc: 0.919434\tvalid_1's auc: 0.825925\n",
      "Fold 4\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[275]\ttraining's auc: 0.878106\tvalid_1's auc: 0.812298\n",
      "best_score is 0.34702081837760224\n",
      "Fold 0\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/woody/anaconda3/lib/python3.8/site-packages/lightgbm/engine.py:181: UserWarning: 'early_stopping_rounds' argument is deprecated and will be removed in a future release of LightGBM. Pass 'early_stopping()' callback via 'callbacks' argument instead.\n",
      "  _log_warning(\"'early_stopping_rounds' argument is deprecated and will be removed in a future release of LightGBM. \"\n",
      "/home/woody/anaconda3/lib/python3.8/site-packages/lightgbm/engine.py:239: UserWarning: 'verbose_eval' argument is deprecated and will be removed in a future release of LightGBM. Pass 'log_evaluation()' callback via 'callbacks' argument instead.\n",
      "  _log_warning(\"'verbose_eval' argument is deprecated and will be removed in a future release of LightGBM. \"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[254]\ttraining's auc: 0.954045\tvalid_1's auc: 0.914889\n",
      "Fold 1\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[292]\ttraining's auc: 0.956964\tvalid_1's auc: 0.927802\n",
      "Fold 2\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[495]\ttraining's auc: 0.968758\tvalid_1's auc: 0.920606\n",
      "Fold 3\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[459]\ttraining's auc: 0.969653\tvalid_1's auc: 0.911877\n",
      "Fold 4\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[287]\ttraining's auc: 0.959269\tvalid_1's auc: 0.907783\n",
      "best_score is 0.4677966101694916\n",
      "Fold 0\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/woody/anaconda3/lib/python3.8/site-packages/lightgbm/engine.py:181: UserWarning: 'early_stopping_rounds' argument is deprecated and will be removed in a future release of LightGBM. Pass 'early_stopping()' callback via 'callbacks' argument instead.\n",
      "  _log_warning(\"'early_stopping_rounds' argument is deprecated and will be removed in a future release of LightGBM. \"\n",
      "/home/woody/anaconda3/lib/python3.8/site-packages/lightgbm/engine.py:239: UserWarning: 'verbose_eval' argument is deprecated and will be removed in a future release of LightGBM. Pass 'log_evaluation()' callback via 'callbacks' argument instead.\n",
      "  _log_warning(\"'verbose_eval' argument is deprecated and will be removed in a future release of LightGBM. \"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[242]\ttraining's auc: 0.952443\tvalid_1's auc: 0.890143\n",
      "Fold 1\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[359]\ttraining's auc: 0.958576\tvalid_1's auc: 0.896315\n",
      "Fold 2\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[116]\ttraining's auc: 0.93506\tvalid_1's auc: 0.90619\n",
      "Fold 3\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[355]\ttraining's auc: 0.958996\tvalid_1's auc: 0.901865\n",
      "Fold 4\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[281]\ttraining's auc: 0.95113\tvalid_1's auc: 0.913377\n",
      "best_score is 0.38522674146797564\n",
      "Fold 0\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/woody/anaconda3/lib/python3.8/site-packages/lightgbm/engine.py:181: UserWarning: 'early_stopping_rounds' argument is deprecated and will be removed in a future release of LightGBM. Pass 'early_stopping()' callback via 'callbacks' argument instead.\n",
      "  _log_warning(\"'early_stopping_rounds' argument is deprecated and will be removed in a future release of LightGBM. \"\n",
      "/home/woody/anaconda3/lib/python3.8/site-packages/lightgbm/engine.py:239: UserWarning: 'verbose_eval' argument is deprecated and will be removed in a future release of LightGBM. Pass 'log_evaluation()' callback via 'callbacks' argument instead.\n",
      "  _log_warning(\"'verbose_eval' argument is deprecated and will be removed in a future release of LightGBM. \"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[293]\ttraining's auc: 0.926067\tvalid_1's auc: 0.852214\n",
      "Fold 1\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[417]\ttraining's auc: 0.940042\tvalid_1's auc: 0.861401\n",
      "Fold 2\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "[1000]\ttraining's auc: 0.981037\tvalid_1's auc: 0.847395\n",
      "Early stopping, best iteration is:\n",
      "[893]\ttraining's auc: 0.975912\tvalid_1's auc: 0.848596\n",
      "Fold 3\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[275]\ttraining's auc: 0.924691\tvalid_1's auc: 0.835335\n",
      "Fold 4\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[95]\ttraining's auc: 0.897096\tvalid_1's auc: 0.839153\n",
      "best_score is 0.32371983519717484\n",
      "Fold 0\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/woody/anaconda3/lib/python3.8/site-packages/lightgbm/engine.py:181: UserWarning: 'early_stopping_rounds' argument is deprecated and will be removed in a future release of LightGBM. Pass 'early_stopping()' callback via 'callbacks' argument instead.\n",
      "  _log_warning(\"'early_stopping_rounds' argument is deprecated and will be removed in a future release of LightGBM. \"\n",
      "/home/woody/anaconda3/lib/python3.8/site-packages/lightgbm/engine.py:239: UserWarning: 'verbose_eval' argument is deprecated and will be removed in a future release of LightGBM. Pass 'log_evaluation()' callback via 'callbacks' argument instead.\n",
      "  _log_warning(\"'verbose_eval' argument is deprecated and will be removed in a future release of LightGBM. \"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[363]\ttraining's auc: 0.951001\tvalid_1's auc: 0.898582\n",
      "Fold 1\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[278]\ttraining's auc: 0.944177\tvalid_1's auc: 0.911397\n",
      "Fold 2\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[390]\ttraining's auc: 0.951826\tvalid_1's auc: 0.904881\n",
      "Fold 3\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "[1000]\ttraining's auc: 0.979827\tvalid_1's auc: 0.898618\n",
      "Early stopping, best iteration is:\n",
      "[583]\ttraining's auc: 0.962727\tvalid_1's auc: 0.900538\n",
      "Fold 4\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "Early stopping, best iteration is:\n",
      "[291]\ttraining's auc: 0.944898\tvalid_1's auc: 0.91346\n",
      "best_score is 0.5246733477102626\n",
      "avg_f1 is 0.4096874705845014\n"
     ]
    }
   ],
   "source": [
    "X_train = df_train[features]\n",
    "X_test = df_test[features]\n",
    "\n",
    "result = pd.DataFrame({'CUST_NO':df_test.CUST_NO})\n",
    "oof_result = pd.DataFrame()\n",
    "feature_importance_df = pd.DataFrame()\n",
    "thres_result = []\n",
    "final_score = 0\n",
    "\n",
    "for label in labels:\n",
    "    y = df_train[label]\n",
    "\n",
    "    oof = np.zeros(X_train.shape[0])\n",
    "    predictions = np.zeros(X_test.shape[0])\n",
    "    \n",
    "    seeds =2019\n",
    "\n",
    "    folds = StratifiedKFold(n_splits=5, random_state=2019, shuffle=True)\n",
    "\n",
    "    expect_vals = np.zeros(2)\n",
    "    shap_vals = np.zeros((2,X_train.shape[0]))\n",
    "\n",
    "    for fold_, (trn_idx, val_idx) in enumerate(folds.split(X_train.values, y.values)):\n",
    "        print(\"Fold {}\".format(fold_))\n",
    "        trn_data = lgb.Dataset(X_train.iloc[trn_idx], label=y.iloc[trn_idx])\n",
    "        val_data = lgb.Dataset(X_train.iloc[val_idx], label=y.iloc[val_idx])\n",
    "        num_round = 15000\n",
    "        clf = lgb.train(params, trn_data, num_round, valid_sets = [trn_data, val_data], verbose_eval=1000, early_stopping_rounds = 500)\n",
    "        oof[val_idx] = clf.predict(X_train.iloc[val_idx], num_iteration=clf.best_iteration)\n",
    "\n",
    "        fold_importance_df = pd.DataFrame()\n",
    "        fold_importance_df[\"feature\"] = clf.feature_name()\n",
    "        fold_importance_df[\"importance\"] = clf.feature_importance(importance_type='gain')\n",
    "        fold_importance_df[\"fold\"] = fold_ + 1\n",
    "        fold_importance_df[\"label\"] = label\n",
    "        feature_importance_df = pd.concat([feature_importance_df, fold_importance_df], axis=0)   \n",
    "        predictions += clf.predict(X_test, num_iteration=clf.best_iteration) / folds.n_splits\n",
    "        \n",
    "    oof_result[str(label)] = oof\n",
    "    \n",
    "    thresholds = np.arange(0,1,0.01) \n",
    "    f1_scores = []\n",
    "    for x in thresholds:\n",
    "        pred_label = np.where(oof>x,1,0)\n",
    "        score = f1_score(y,pred_label)\n",
    "        f1_scores.append(score)\n",
    "    best_score = np.max(f1_scores)\n",
    "    print('best_score is {}'.format(best_score))\n",
    "    thres_result.append(thresholds[np.argmax(f1_scores)])\n",
    "    final_score += best_score / folds.n_splits\n",
    "    \n",
    "    result[label] = predictions\n",
    "print('avg_f1 is {}'.format(final_score))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:57:32.795347Z",
     "iopub.status.busy": "2023-11-08T00:57:32.795154Z",
     "iopub.status.idle": "2023-11-08T00:57:32.798981Z",
     "shell.execute_reply": "2023-11-08T00:57:32.798523Z",
     "shell.execute_reply.started": "2023-11-08T00:57:32.795320Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0.17, 0.24, 0.19, 0.17, 0.25]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "thres_result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:57:32.799912Z",
     "iopub.status.busy": "2023-11-08T00:57:32.799741Z",
     "iopub.status.idle": "2023-11-08T00:57:33.411550Z",
     "shell.execute_reply": "2023-11-08T00:57:33.411064Z",
     "shell.execute_reply.started": "2023-11-08T00:57:32.799889Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.4050531180149183"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tmp_oof_result = oof_result\n",
    "\n",
    "for i, col in enumerate(labels):\n",
    "    tmp_oof_result[col] = tmp_oof_result[col].apply(lambda x: 1 if x>=thres_result[i] else 0)\n",
    "\n",
    "local_f1(tmp_oof_result[labels], df_train[labels])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:57:33.412605Z",
     "iopub.status.busy": "2023-11-08T00:57:33.412415Z",
     "iopub.status.idle": "2023-11-08T00:57:33.433085Z",
     "shell.execute_reply": "2023-11-08T00:57:33.432586Z",
     "shell.execute_reply.started": "2023-11-08T00:57:33.412580Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "tmp_result = result.copy()\n",
    "\n",
    "for i, col in enumerate(labels):\n",
    "    result[col] = tmp_result[col].apply(lambda x: 1 if x>=thres_result[i] else 0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:57:33.434037Z",
     "iopub.status.busy": "2023-11-08T00:57:33.433856Z",
     "iopub.status.idle": "2023-11-08T00:57:33.446470Z",
     "shell.execute_reply": "2023-11-08T00:57:33.445986Z",
     "shell.execute_reply.started": "2023-11-08T00:57:33.434007Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    55385\n",
      "1     4615\n",
      "Name: TD_IND, dtype: int64\n",
      "0    57158\n",
      "1     2842\n",
      "Name: FNCG_IND, dtype: int64\n",
      "0    57504\n",
      "1     2496\n",
      "Name: FUND_IND, dtype: int64\n",
      "0    57681\n",
      "1     2319\n",
      "Name: INSUR_IND, dtype: int64\n",
      "0    56252\n",
      "1     3748\n",
      "Name: IL_IND, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "for col in labels:\n",
    "    print(df_train[col].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:57:33.447356Z",
     "iopub.status.busy": "2023-11-08T00:57:33.447186Z",
     "iopub.status.idle": "2023-11-08T00:57:33.456414Z",
     "shell.execute_reply": "2023-11-08T00:57:33.455937Z",
     "shell.execute_reply.started": "2023-11-08T00:57:33.447335Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    4214\n",
      "1     786\n",
      "Name: TD_IND, dtype: int64\n",
      "0    4668\n",
      "1     332\n",
      "Name: FNCG_IND, dtype: int64\n",
      "0    4693\n",
      "1     307\n",
      "Name: FUND_IND, dtype: int64\n",
      "0    4780\n",
      "1     220\n",
      "Name: INSUR_IND, dtype: int64\n",
      "0    4648\n",
      "1     352\n",
      "Name: IL_IND, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "for col in labels:\n",
    "    print(result[col].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-08T00:57:33.457267Z",
     "iopub.status.busy": "2023-11-08T00:57:33.457102Z",
     "iopub.status.idle": "2023-11-08T00:57:33.480862Z",
     "shell.execute_reply": "2023-11-08T00:57:33.480383Z",
     "shell.execute_reply.started": "2023-11-08T00:57:33.457246Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "test_0.4096874705845014.csv\n"
     ]
    }
   ],
   "source": [
    "result.to_csv('test_{}.csv'.format(final_score),index=False,header=None)\n",
    "print('test_{}.csv'.format(final_score))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-15T08:08:18.366398Z",
     "iopub.status.busy": "2023-11-15T08:08:18.366122Z",
     "iopub.status.idle": "2023-11-15T08:08:19.076798Z",
     "shell.execute_reply": "2023-11-15T08:08:19.076184Z",
     "shell.execute_reply.started": "2023-11-15T08:08:18.366368Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Magic init complete.\n",
      "Predict init complete.\n",
      "Matplotlib env init complete.\n",
      "Gbase数据库信息配置为空，相关魔法命令不可使用（%sql, %df2db等），如有需求，请联系管理员配置或自行配置\n"
     ]
    }
   ],
   "source": [
    "init_woody"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-15T08:08:19.977080Z",
     "iopub.status.busy": "2023-11-15T08:08:19.976826Z",
     "iopub.status.idle": "2023-11-15T08:08:20.419529Z",
     "shell.execute_reply": "2023-11-15T08:08:20.419042Z",
     "shell.execute_reply.started": "2023-11-15T08:08:19.977051Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'请稍后使用命令: %query_predict problem_id 查看评分结果, problem_id为阶段序号，取值为：1,2, 比如查询第一阶段的评分结果: %query_predict 1'"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%predict 5 test_0.4096874705845014.csv"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-15T08:08:24.690061Z",
     "iopub.status.busy": "2023-11-15T08:08:24.689771Z",
     "iopub.status.idle": "2023-11-15T08:08:24.951721Z",
     "shell.execute_reply": "2023-11-15T08:08:24.951183Z",
     "shell.execute_reply.started": "2023-11-15T08:08:24.690023Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "最近三次评分提交的结果供参考(大模型程序评分需要一些时间，请耐心等待，只有评分完成的结果会显示在下面的列表中):\n",
      "\n",
      "提交时间：2023-11-15 16:08:20 \t 评分结果：0.4142     \t 评分成功\n",
      "提交时间：2023-11-15 10:34:21 \t 评分结果：0.4142     \t 评分成功\n",
      "提交时间：2023-11-14 23:23:05 \t 评分结果：0.4218     \t 评分成功\n"
     ]
    }
   ],
   "source": [
    "%query_predict 5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.18"
  },
  "toc-showcode": true
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
